#include "../decoder_conf.h"

#if DECODER_THREAD == DECODER_THREAD_FREERTOS
#include "../decoder_thread.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

using ThreadFunction = void (*)(void *);

struct Thread
{
    TaskHandle_t task;
    SemaphoreHandle_t joinSem;
};

void *DecoderThread::semCreate(int value)
{
    SemaphoreHandle_t sem = xSemaphoreCreateCounting(1, value); 

    return sem;
}

void DecoderThread::semPost(void *sem)
{
    xSemaphoreGive((SemaphoreHandle_t)sem);
}

void DecoderThread::semWait(void *sem)
{
    xSemaphoreTake((SemaphoreHandle_t)sem, portMAX_DELAY);
}

void DecoderThread::semDestroy(void *sem)
{
    vSemaphoreDelete((SemaphoreHandle_t)sem);
}

void *DecoderThread::threadCreate(void *function, void *arg, size_t stackSize)
{
    Thread *thread = new Thread;

    // 创建信号量
    thread->joinSem = xSemaphoreCreateBinary();

    // 创建线程
    xTaskCreate(
        (ThreadFunction)function,
        "decode thread",
        stackSize == 0 ? FREERTOS_TASK_DEFAULT_STACK_SIZE : stackSize,
        arg,
        1,
        &thread->task); 

    return (void *)thread;
}

void DecoderThread::threadJoin(void *thread)
{
    Thread *t = (Thread *)thread;

    xSemaphoreTake(t->joinSem, portMAX_DELAY);

    vSemaphoreDelete(t->joinSem);

    delete t;
}

void DecoderThread::threadExit(void *thread)
{
    Thread *t = (Thread *)thread;
    
    xSemaphoreGive(t->joinSem);
    vTaskDelete(nullptr); // 删除任务
}

void DecoderThread::mSleep(uint32_t ms)
{
    vTaskDelay(ms * portTICK_PERIOD_MS);
}


#endif
